import httpx
import logging
import asyncio
import time
from app.core.config import settings
from app.core.logging_config import get_external_api_logger

# 获取外部API专用日志记录器
external_api_logger = get_external_api_logger()

# 用于存储临时的声音克隆结果
temp_voice_results = {}

async def create_digital_person_v2(data):
    """
    调用V2版本的外部API创建数字人
    
    Args:
        data (dict): 包含name, url, callback的字典
    
    Returns:
        tuple: (response_data, status_code)
    """
    api_url = settings.EXTERNAL_API_V2_URL
    headers = {
        'authorization': settings.EXTERNAL_API_V2_AUTH,
        'platform': settings.EXTERNAL_API_V2_PLATFORM,
        'Content-Type': 'application/json'
    }
    
    external_api_logger.info(f"准备调用V2数字人创建API")
    external_api_logger.info(f"API地址: {api_url}")
    external_api_logger.info(f"请求头: {headers}")
    external_api_logger.info(f"请求数据: {data}")
    
    try:
        async with httpx.AsyncClient(timeout=30.0) as client:
            external_api_logger.info(f"开始发送HTTP POST请求")
            response = await client.post(api_url, json=data, headers=headers)
            
            external_api_logger.info(f"收到响应 - 状态码: {response.status_code}")
            external_api_logger.info(f"响应头: {dict(response.headers)}")
            
            try:
                response_data = response.json()
                external_api_logger.info(f"响应数据: {response_data}")
            except Exception as json_error:
                external_api_logger.error(f"解析响应JSON失败: {json_error}")
                response_data = {"error": "Invalid JSON response", "raw_response": response.text}
                external_api_logger.info(f"原始响应文本: {response.text}")
            
            if response.status_code == 200:
                external_api_logger.info(f"V2数字人创建API调用成功")
            else:
                external_api_logger.error(f"V2数字人创建API调用失败 - 状态码: {response.status_code}")
            
            return response_data, response.status_code
            
    except httpx.TimeoutException as e:
        external_api_logger.error(f"V2数字人创建API请求超时: {e}")
        return {"error": "Request timeout"}, 408
    except httpx.RequestError as e:
        external_api_logger.error(f"V2数字人创建API请求错误: {e}")
        return {"error": str(e)}, 500
    except Exception as e:
        external_api_logger.error(f"V2数字人创建API调用异常: {e}")
        return {"error": str(e)}, 500

async def create_voice_clone_v2(data):
    """
    调用V2版本的外部API创建声音克隆
    
    Args:
        data (dict): 包含name, url, voiceType, callback的字典
    
    Returns:
        tuple: (response_data, status_code)
    """
    api_url = settings.EXTERNAL_VOICE_V2_URL
    headers = {
        'authorization': settings.EXTERNAL_VOICE_V2_AUTH,
        'platform': settings.EXTERNAL_VOICE_V2_PLATFORM,
        'Content-Type': 'application/json'
    }
    
    external_api_logger.info(f"准备调用V2声音克隆API")
    external_api_logger.info(f"API地址: {api_url}")
    external_api_logger.info(f"请求头: {headers}")
    external_api_logger.info(f"请求数据: {data}")
    
    try:
        async with httpx.AsyncClient(timeout=30.0) as client:
            external_api_logger.info(f"开始发送HTTP POST请求")
            response = await client.post(api_url, json=data, headers=headers)
            
            external_api_logger.info(f"收到响应 - 状态码: {response.status_code}")
            external_api_logger.info(f"响应头: {dict(response.headers)}")
            
            try:
                response_data = response.json()
                external_api_logger.info(f"响应数据: {response_data}")
            except Exception as json_error:
                external_api_logger.error(f"解析响应JSON失败: {json_error}")
                response_data = {"error": "Invalid JSON response", "raw_response": response.text}
                external_api_logger.info(f"原始响应文本: {response.text}")
            
            if response.status_code == 200:
                external_api_logger.info(f"V2声音克隆API调用成功")
                # 记录返回的jobId
                job_id = response_data.get('data', {}).get('jobId') if isinstance(response_data, dict) else None
                if job_id:
                    external_api_logger.info(f"获取到jobId: {job_id}")
                else:
                    external_api_logger.warning(f"响应中未找到jobId")
            else:
                external_api_logger.error(f"V2声音克隆API调用失败 - 状态码: {response.status_code}")
            
            return response_data, response.status_code
            
    except httpx.TimeoutException as e:
        external_api_logger.error(f"V2声音克隆API请求超时: {e}")
        return {"error": "Request timeout"}, 408
    except httpx.RequestError as e:
        external_api_logger.error(f"V2声音克隆API请求错误: {e}")
        return {"error": str(e)}, 500
    except Exception as e:
        external_api_logger.error(f"调用V2声音克隆API时发生异常: {e}")
        return {'error': str(e)}, 500

async def create_videomix_v2(data):
    """
    调用V2版本的外部API创建作品
    
    Args:
        data (dict): 包含name, personUrl, callback, content, voiceTid, voiceType的字典
    
    Returns:
        tuple: (response_data, status_code)
    """
    api_url = settings.EXTERNAL_VIDEOMIX_V2_URL
    headers = {
        'authorization': settings.EXTERNAL_VIDEOMIX_V2_AUTH,
        'platform': settings.EXTERNAL_VIDEOMIX_V2_PLATFORM,
        'Content-Type': 'application/json'
    }
    
    external_api_logger.info(f"准备调用V2作品创建API")
    external_api_logger.info(f"API地址: {api_url}")
    external_api_logger.info(f"请求头: {headers}")
    external_api_logger.info(f"请求数据: {data}")
    
    try:
        async with httpx.AsyncClient(timeout=30.0) as client:
            response = await client.post(api_url, json=data, headers=headers)
            status_code = response.status_code
            
            try:
                response_data = response.json()
            except:
                response_data = {'error': 'Invalid JSON response', 'raw_response': response.text}
            
            external_api_logger.info(f"V2作品创建API响应状态码: {status_code}")
            external_api_logger.info(f"V2作品创建API响应数据: {response_data}")
            
            return response_data, status_code
            
    except httpx.TimeoutException:
        external_api_logger.error("调用V2作品创建API超时")
        return {'error': 'Request timeout'}, 408
    except httpx.RequestError as e:
        external_api_logger.error(f"调用V2作品创建API时发生请求错误: {e}")
        return {'error': str(e)}, 500
    except Exception as e:
        external_api_logger.error(f"调用V2作品创建API时发生异常: {e}")
        return {'error': str(e)}, 500

async def create_voice_clone_internal(data, request_id):
    """
    内部声音克隆函数 - 专门用于重新训练获取speaker_id的情况
    不经过优速AI扣费验证，直接调用外部API进行声音克隆
    
    Args:
        data (dict): 包含name, url, voiceType的字典
        request_id (str): 请求ID，用于标识和追踪
    
    Returns:
        tuple: (speaker_id, success, error_message)
    """
    external_api_logger.info(f"[{request_id}] ===== 开始内部声音克隆（不扣费） =====")
    external_api_logger.info(f"[{request_id}] 这是重新训练获取speaker_id的内部调用，不会向用户扣费")
    
    # 为内部声音克隆生成特殊的callback URL
    internal_callback_url = f"{settings.V2_VOICE_CALLBACK_URL}?internal=1&request_id={request_id}"
    
    # 构建请求数据
    voice_data = {
        'name': data.get('name', f'internal_voice_{request_id}'),
        'url': data['url'],
        'voiceType': data.get('voiceType', 'lite'),
        'callback': internal_callback_url
    }
    
    external_api_logger.info(f"[{request_id}] 内部声音克隆请求数据: {voice_data}")
    
    try:
        # 直接调用外部API，不经过优速AI验证
        response_data, status_code = await create_voice_clone_v2(voice_data)
        
        if status_code == 200 and response_data.get('data', {}).get('jobId'):
            job_id = response_data['data']['jobId']
            external_api_logger.info(f"[{request_id}] 内部声音克隆任务已提交，jobId: {job_id}")
            
            # 初始化结果存储
            temp_voice_results[request_id] = {
                'job_id': job_id,
                'status': 'pending',
                'speaker_id': None,
                'error': None,
                'timestamp': time.time(),
                'type': 'internal'  # 标记为内部调用
            }
            
            # 等待回调结果（最多等待120秒）
            max_wait_time = 240
            check_interval = 2
            elapsed_time = 0
            
            external_api_logger.info(f"[{request_id}] 开始等待内部声音克隆回调结果，最大等待时间: {max_wait_time}秒")
            
            while elapsed_time < max_wait_time:
                await asyncio.sleep(check_interval)
                elapsed_time += check_interval
                
                # 检查结果
                if request_id in temp_voice_results:
                    result = temp_voice_results[request_id]
                    if result['status'] == 'success':
                        speaker_id = result['speaker_id']
                        external_api_logger.info(f"[{request_id}] 内部声音克隆成功，获取到speaker_id: {speaker_id}")
                        # 清理临时结果
                        del temp_voice_results[request_id]
                        external_api_logger.info(f"[{request_id}] ===== 内部声音克隆完成（无扣费） =====")
                        return speaker_id, True, None
                    elif result['status'] == 'failed':
                        error_msg = result['error'] or '内部声音克隆失败'
                        external_api_logger.error(f"[{request_id}] 内部声音克隆失败: {error_msg}")
                        # 清理临时结果
                        del temp_voice_results[request_id]
                        return None, False, error_msg
                
                external_api_logger.info(f"[{request_id}] 等待内部声音克隆结果中... ({elapsed_time}/{max_wait_time}秒)")
            
            # 超时处理
            external_api_logger.error(f"[{request_id}] 等待内部声音克隆结果超时")
            if request_id in temp_voice_results:
                del temp_voice_results[request_id]
            return None, False, "内部声音克隆超时"
            
        else:
            error_msg = f"内部声音克隆API调用失败，状态码: {status_code}"
            external_api_logger.error(f"[{request_id}] {error_msg}")
            return None, False, error_msg
            
    except Exception as e:
        error_msg = f"调用内部声音克隆API异常: {str(e)}"
        external_api_logger.error(f"[{request_id}] {error_msg}")
        return None, False, error_msg

# 保留原有的同步声音克隆函数作为兼容性
async def create_voice_clone_v2_sync(data, request_id):
    """
    同步调用V2版本的外部API创建声音克隆（用于作品创建时的临时声音克隆）
    注意：此函数已被 create_voice_clone_internal 替代，建议使用新函数
    
    Args:
        data (dict): 包含name, url, voiceType的字典（不需要callback）
        request_id (str): 请求ID，用于标识和追踪
    
    Returns:
        tuple: (speaker_id, success, error_message)
    """
    external_api_logger.warning(f"[{request_id}] 使用了旧的 create_voice_clone_v2_sync 函数，建议使用 create_voice_clone_internal")
    
    # 直接调用新的内部声音克隆函数
    return await create_voice_clone_internal(data, request_id)

def update_temp_voice_result(request_id, status, speaker_id=None, error=None):
    """
    更新临时声音克隆结果（由回调接口调用）
    
    Args:
        request_id (str): 请求ID
        status (str): 状态 ('success' 或 'failed')
        speaker_id (str): speaker_id（成功时）
        error (str): 错误信息（失败时）
    """
    if request_id in temp_voice_results:
        result_type = temp_voice_results[request_id].get('type', 'unknown')
        temp_voice_results[request_id].update({
            'status': status,
            'speaker_id': speaker_id,
            'error': error,
            'timestamp': time.time()
        })
        external_api_logger.info(f"[{request_id}] 更新声音克隆结果({result_type}): status={status}, speaker_id={speaker_id}") 